"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from PyQt4 import QtCore
from PyQt4 import QtGui
from msnp.gui import UIText, Resources, GUIHelper, MyStyle
from msnp.logger import Logger
from msnp import gui

class AudioWidget(QtGui.QDialog):
    """This class represents an audio widget which displays the contents of the table audio of the media database.
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing either a AudioSplashWidget object or an AudioListWidget.
        __audioSplashWidget: An AudioSplashWidget object.
        __audioTableWidget: An AudioListWidget object.
    """
    def __init__(self, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__audioSplashWidget = None
        self.__audioTableWidget = None
        self.__mainLayout = QtGui.QVBoxLayout()
        self.setLayout(self.__mainLayout)
#        self.setModal(True)
        
    def buildAudioTableWidget(self, tableWidget):
        """Initializes the item __mainLayout and adds the given AudioListWidget to it."""
        self.setWindowTitle(UIText.TITLE_AUDIO_LIST)
        self.setWindowIcon(QtGui.QIcon(Resources.IMAGE_AUDIO_LIST_ICON))
        self.__cleanLayout()
        self.__audioTableWidget = tableWidget
        self.__mainLayout.addWidget(self.__audioTableWidget)
        self.setFixedSize(1000, 700)
        self.repaint()
        GUIHelper.centerWidget(self)
        
    def buildAudioSplashWidget(self):
        """Initializes the item __mainLayout by creating a new AudioSplashWidget."""
        self.setWindowTitle(UIText.TITLE_PLEASE_WAIT)
        self.setWindowIcon(QtGui.QIcon(Resources.IMAGE_AUDIO_LIST_ICON))
        self.__cleanLayout()
        self.__audioSplashWidget = AudioSplashWidget()
        self.__mainLayout.addWidget(self.__audioSplashWidget)
        self.setFixedSize(1000, 700)
        self.repaint()
        GUIHelper.centerWidget(self)
        
    def __cleanLayout(self):
        """Removes all entries from the item __mainLayout."""
        import sip
        if self.layout() != None:
            oldLayout = self.layout()
            for i in reversed(range(oldLayout.count())):
                oldLayout.itemAt(i).widget().setParent(None)
            sip.delete(oldLayout)
        self.__mainLayout = QtGui.QVBoxLayout()
        self.setLayout(self.__mainLayout)

    def closeEvent(self, event):
        """This method is called when the window is closed."""
        gui.GUIController.closeAudioTableWidget()
        event.accept()

class AudioSplashWidget(QtGui.QWidget):
    """This class represents an audio splash widget which is displayed during loading from the database the data to display. 
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing the items __lblSplash and __lblLoading.
        __lblSplash: A QLabel object.
        __lblLoading: A QLabel object containing the item __movie.
        __movie: A QMovie object.
    """
    def __init__(self, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__mainLayout = QtGui.QVBoxLayout()
        self.__build()
        self.setLayout(self.__mainLayout)
        
    def __build(self): 
        """Initializes the item __mainLayout and adds its contained items."""
        self.__initSplashLabels()
        self.__mainLayout.addWidget(self.__lblSplash)
        self.__mainLayout.addWidget(self.__lblLoading)
        
    def __initSplashLabels(self):
        """Initializes the items __lblSplash and __lblLoading and adds its contained items."""
        #movie container
        self.__lblSplash = QtGui.QLabel()
#        self.__lblSplash.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        self.__lblSplash.setAlignment(QtCore.Qt.AlignCenter)
        #create movie
        self.__movie = QtGui.QMovie(Resources.IMAGE_LOADING, QtCore.QByteArray(), self)
        self.__movie.setCacheMode(QtGui.QMovie.CacheAll)
        self.__movie.setSpeed(100)
        self.__lblSplash.setMovie(self.__movie)
        self.__movie.start()
        self.__lblLoading = QtGui.QLabel(UIText.LABEL_LOADING_TRACK_LIST)
        self.__lblLoading.setAlignment(QtCore.Qt.AlignHCenter)
        
        
class AudioListWidget(QtGui.QWidget):
    """This class represents an audio list widget which displays the contents of the table audio of the media database.
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing the items __lblSplash and __lblLoading.
        __contentWidget: A QWidget object containing the items __lblTitle and __table.
        __lblTitle: A QLabel object.
        __table: An AutioTable containing the data to display.
    """
    def __init__(self, audios, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__audios = audios
        self.__mainLayout = QtGui.QVBoxLayout()
        self.__build()
        self.setLayout(self.__mainLayout)
        
    def __build(self):
        """Initializes the item __mainLayout and adds its contained items."""
        self.__initLabel()
        self.__initTable()
        self.__initContentWidget()
        self.__mainLayout.addWidget(self.__contentWidget)
        
    def __initContentWidget(self):
        """Initializes the QWidget object __contentWidget."""
        vLayout = QtGui.QVBoxLayout()
        vLayout.addWidget(self.__lblTitle)
        vLayout.addWidget(self.__table)
        self.__contentWidget = QtGui.QWidget()
        self.__contentWidget.setLayout(vLayout)
        
    def __initLabel(self):
        """Initializes the QLabel object __lblTitle."""
        self.__lblTitle = QtGui.QLabel(UIText.TITLE_AUDIO_LIST)
        self.__lblTitle.setFont(MyStyle.getFont18Bold())
        self.__lblTitle.setAlignment(QtCore.Qt.AlignCenter)
        
    def __initTable(self):
        """Initializes the AutioTable object __table."""
        self.__table = AudioTable(self.__audios)
        

class AudioTable(QtGui.QTableWidget):
    """This class represents the audio table where the data from the table audio of the media database is displayed.
    
    Parameters:
        __audios: A list of Audio objects to be displayed.
        __NUM_COLUMNS: An integer value representing the number of columns the table has.
    """
    def __init__(self, audios):
        """The init-method."""
        QtGui.QTableWidget.__init__(self)
        self.__NUM_COLUMNS = 9
        self.__audios = audios
        self.setColumnCount(self.__NUM_COLUMNS)
        rowCount = 0
        if self.__audios != None and len(self.__audios) > 0:
            rowCount = len(self.__audios)
        self.setRowCount(rowCount)
        self.setSortingEnabled(True)
        self.__build()
        
    def __build(self):
        """Initializes the contained items."""
        Logger.info("audio list size: " + str(len(self.__audios)))
        self.__initHeaders()
        self.__initRows()
        self.connect(self, QtCore.SIGNAL("cellDoubleClicked (int,int)"), self.cellDoubleClicked)
        
    def __initHeaders(self):
        """Initializes the headers of the table."""
        itemHeaderTitle = QtGui.QTableWidgetItem(UIText.AT_TITLE)
        itemHeaderArtist = QtGui.QTableWidgetItem(UIText.AT_ARTIST)
        itemHeaderCollection = QtGui.QTableWidgetItem(UIText.AT_COLLECTION)
        itemHeaderGenre = QtGui.QTableWidgetItem(UIText.AT_GENRE)
        itemHeaderYear = QtGui.QTableWidgetItem(UIText.AT_YEAR)
        itemHeaderComposer = QtGui.QTableWidgetItem(UIText.AT_COMPOSER)
        itemHeaderLyrics = QtGui.QTableWidgetItem(UIText.AT_LYRICS)
        itemHeaderTracknumber = QtGui.QTableWidgetItem(UIText.AT_TRACKNUMBER)
        itemHeaderDiscnumber = QtGui.QTableWidgetItem(UIText.AT_DISCNUMBER)
        self.setHorizontalHeaderItem(0, itemHeaderTitle)
        self.setHorizontalHeaderItem(1, itemHeaderArtist)
        self.setHorizontalHeaderItem(2, itemHeaderCollection)
        self.setHorizontalHeaderItem(3, itemHeaderGenre)
        self.setHorizontalHeaderItem(4, itemHeaderYear)
        self.setHorizontalHeaderItem(5, itemHeaderComposer)
        self.setHorizontalHeaderItem(6, itemHeaderLyrics)
        self.setHorizontalHeaderItem(7, itemHeaderTracknumber)
        self.setHorizontalHeaderItem(8, itemHeaderDiscnumber)
        
        self.setColumnWidth(0, 160)
        self.setColumnWidth(4, 50)
        self.setColumnWidth(6, 160)
        self.setColumnWidth(7, 70)
        self.setColumnWidth(8, 70)

        
    def __initRows(self):
        """Initializes the rows."""
#        item = QtGui.QTableWidgetItem("test")
#        self.setItem(0, 0, item)
        
        if self.__audios != None:
            row = 0
            for audio in self.__audios:
                self.__constructRow(row, audio)
                row += 1
            
    def __constructRow(self, row, audio):
        """Initializes a single row with the given Audio object."""
        #prepare strings
        title = audio.getMedia().getTitle()
        Logger.info("preparing audio: " + title)
        artist = audio.getArtist().getName() if (audio.getArtist() != None and audio.getArtist().getName() != None) else ""
        collection = audio.getMedia().getCollection().getName() if (audio.getMedia() != None and audio.getMedia().getCollection() != None and audio.getMedia().getCollection().getName() != None) else ""
        genre = audio.getMedia().getGenre().getName() if (audio.getMedia() != None and audio.getMedia().getGenre() != None and audio.getMedia().getGenre().getName() != None) else ""
        year = audio.getMedia().getYear() if (audio.getMedia() != None and audio.getMedia().getYear() != None and audio.getMedia().getYear() != "0") else ""
        composer = audio.getMedia().getComposer() if (audio.getMedia() != None and audio.getMedia().getComposer() != None) else ""
        lyrics = audio.getLyrics() if (audio.getLyrics() != None) else ""
        tracknumber = str(audio.getTracknumber()) if (audio.getTracknumber() != None) else ""
        discnumber = str(audio.getDiscnumber()) if (audio.getDiscnumber() != None) else ""
        #items
        itemTitle = QtGui.QTableWidgetItem(title)
        itemArtist = QtGui.QTableWidgetItem(artist)
        itemCollection = QtGui.QTableWidgetItem(collection)
        itemGenre = QtGui.QTableWidgetItem(genre)
        itemYear = QtGui.QTableWidgetItem(year)
        itemComposer = QtGui.QTableWidgetItem(composer)
        itemLyrics = QtGui.QTableWidgetItem(lyrics)
        itemLyrics.setToolTip(lyrics)
        itemTracknumber = QtGui.QTableWidgetItem(tracknumber)
        itemDiscnumber = QtGui.QTableWidgetItem(discnumber)
        
        itemTitle.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemArtist.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemCollection.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemGenre.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemYear.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemComposer.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemLyrics.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemTracknumber.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemDiscnumber.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)

        #add row
        self.setItem(row, 0, itemTitle)
        self.setItem(row, 1, itemArtist)
        self.setItem(row, 2, itemCollection)
        self.setItem(row, 3, itemGenre)
        self.setItem(row, 4, itemYear)
        self.setItem(row, 5, itemComposer)
        self.setItem(row, 6, itemLyrics)
        self.setItem(row, 7, itemTracknumber)
        self.setItem(row, 8, itemDiscnumber)

    def cellDoubleClicked(self):
        """This method is connected to the item when double clicking. Opens a RatingWidget object for the selected item."""
        row = self.currentRow()
        if self.__audios != None and row < len(self.__audios):
            audio = self.__audios[row]
            ratings = audio.getMedia().getRatings()
            ratingWidget = RatingWidget(ratings, audio.getMedia().getTitle(), self)
            ratingWidget.show()
            
            
class RatingWidget(QtGui.QDialog):
    """This class represents the rating widget for the Ratings object of an Audio object.
    
    Parameters:
        __ratings: A list of Rating objects to be displayed.
        __mainLayout: A QVBoxLayout object containing a RatingTable object.
    """
    def __init__(self, ratings, title, parent):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__ratings = ratings
        self.setFixedSize(500, 350)
        self.setWindowTitle(title)
        self.setWindowIcon(QtGui.QIcon(Resources.IMAGE_RATING_ICON))
        self.__mainLayout = QtGui.QVBoxLayout()
        self.__build()
        self.setLayout(self.__mainLayout)
        GUIHelper.centerWidget(self)
        
    def __build(self):
        """Initializes the item __mainLayout by creating a RatingTable object."""
        ratingTable = RatingTable(self.__ratings, self)
        self.__mainLayout.addWidget(ratingTable)
            
class RatingTable(QtGui.QTableWidget):
    """This class represents the rating table for a given Ratings object.
    
    Parameters:
        __ratings: A list of Rating objects to be displayed.
        __NUM_COLUMNS: An integer value representing the number of columns of the table.
    """
    def __init__(self, ratings, parent):
        """The init-method."""
        QtGui.QTableWidget.__init__(self, parent)
        self.__NUM_COLUMNS = 5
        self.__ratings = ratings
        self.setColumnCount(self.__NUM_COLUMNS)
        rowCount = 0
        if self.__ratings != None and len(self.__ratings) > 0:
            rowCount = len(self.__ratings)
        self.setRowCount(rowCount)
        self.setSortingEnabled(True)
        self.__build()
        
    def __build(self):
        """Initializes the table."""
        Logger.info("rating list size: " + str(len(self.__ratings)))
        self.__initHeaders()
        self.__initRows()
        
    def __initHeaders(self):
        """Initializes the headers of the table."""
        itemHeaderUsername = QtGui.QTableWidgetItem(UIText.AT_USERNAME)
        itemHeaderScore = QtGui.QTableWidgetItem(UIText.AT_SCORE)
        itemHeaderRating = QtGui.QTableWidgetItem(UIText.AT_RATING)
        itemHeaderPlaycount = QtGui.QTableWidgetItem(UIText.AT_PLAYCOUNT)
        itemHeaderComment = QtGui.QTableWidgetItem(UIText.AT_COMMENT)
        #set columns
        self.setHorizontalHeaderItem(0, itemHeaderUsername)
        self.setHorizontalHeaderItem(1, itemHeaderScore)
        self.setHorizontalHeaderItem(2, itemHeaderRating)
        self.setHorizontalHeaderItem(3, itemHeaderPlaycount)
        self.setHorizontalHeaderItem(4, itemHeaderComment)
        self.setColumnWidth(1, 75)
        self.setColumnWidth(2, 75)
        self.setColumnWidth(3, 75)
        self.setColumnWidth(4, 130)

    def __initRows(self):
        """Initializes the rows of the table."""
        if self.__ratings != None:
            row = 0
            for rating in self.__ratings:
                self.__constructRow(row, rating)
                row += 1
            
    def __constructRow(self, row, rating):
        """Initializes a single row with the values of the given Ratings object."""
        username = rating.getUsername()
        score = str(rating.getScore())
        ratingString = str(rating.getRating())
        playcount = str(rating.getPlaycount())
        comment = ""
        if rating.getComment() != None:
            comment = rating.getComment()
        #items
        itemUsername = QtGui.QTableWidgetItem(username)
        itemScore = QtGui.QTableWidgetItem(score)
        itemRating = QtGui.QTableWidgetItem(ratingString)
        itemPlaycount = QtGui.QTableWidgetItem(playcount)
        itemComment = QtGui.QTableWidgetItem(comment)
        itemComment.setToolTip(comment)
        itemUsername.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemScore.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemRating.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemPlaycount.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        itemComment.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        #add row
        self.setItem(row, 0, itemUsername)
        self.setItem(row, 1, itemScore)
        self.setItem(row, 2, itemRating)
        self.setItem(row, 3, itemPlaycount)
        self.setItem(row, 4, itemComment)
        
